/*
 * File:    HttpPostHandler.java
 * Created: 17-Sep-2007
 * Version: $Id$
 * 
 * COPYRIGHT (C) 2007, Bitgate Software, LLC.  All Rights Reserved.
 *
 * software@bitgatesoftware.com
 */

package com.bitgate.util.service.protocol.http.handler;

import static com.bitgate.util.debug.Debug.debug;
import static com.bitgate.util.debug.Debug.isDebugEnabled;

import com.bitgate.util.bytes.ByteString;
import com.bitgate.util.service.protocol.http.HttpClientContext;
import com.bitgate.util.service.protocol.http.HttpVariableStore;

/**
 * This is the POST handling code, which is abstracted from the {@link AbstractHandler} code.  This code only
 * contains a hook for the &quot;processPostData&quot; call, which is called when posting data is to be parsed.
 * 
 * @author kenji
 * @since 21-Sep-2007
 */
public class HttpPostHandler extends AbstractHandler
{
	/**
	 * Calls the superclass constructor.
	 */
	public HttpPostHandler()
	{
		super();
	}
	
	/**
	 * Processes the post data that was read in by the HTTP implementation.  It checks to make sure the posted length
	 * (in the &quot;Content-Length&quot; header) matches the amount of data posted in the body of the request.
	 * 
	 * @param hcContext The currently active {@link HttpClientContext} object.
	 * @return <code>true</code> if the object post length and content length were exactly the same, indicating an end
	 *     of request, <code>false</code> indicates more data must be read to satisfy the end of request.
	 */
	@Override
	public boolean processPostData(HttpClientContext hcContext)
	{
		if (isDebugEnabled()) {
			if (hcContext.getData() != null) {
				debug("Data='" + new String(hcContext.getData()) + "'");
			}
		}
		
		long postLength = hcContext.getBufferSize() - 2;
		long contentLength = Long.parseLong(hcContext.getHeader(new ByteString("content-length")).toString());
		
		if (isDebugEnabled()) {
			debug("PostLength = '" + postLength + "' DataLength='" + contentLength + "'");
		}
		
		if (postLength == contentLength) {
			byte[] allPostData = getAllPostData(hcContext);
			HttpVariableStore hvStore = new HttpVariableStore();
			
			if (isDebugEnabled()) {
				debug("PostData='" + new String(allPostData) + "'");
			}
			
			hvStore.parse(new String(allPostData),
				(hcContext.getHeader(new ByteString("soapaction")) != null) ? HttpVariableStore.HttpStringType.SOAP :
					HttpVariableStore.HttpStringType.POST);
			
			hcContext.setVariableStore(hvStore);
			
			allPostData = null;
			
			return true;
		}

		return false;
	}

	private byte[] getAllPostData(HttpClientContext hcContext)
	{
		byte[] returnData = new byte[(int) hcContext.getBufferSize()];
		byte[] chunkedData = null;
		int position = 0;
		
		while((chunkedData = hcContext.getBufferChunk()) != null) {
			System.arraycopy(chunkedData, 0, returnData, position, chunkedData.length);
			position += chunkedData.length;
		}
		
		return returnData;
	}
	
}